home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / 3D_Rendering / Musgrave_Shaders / Source / cyclone.sl next >
Encoding:
Text File  |  1994-12-08  |  3.5 KB  |  114 lines

  1. /*
  2.  * cyclone.sl - surface for a semi-opaque cloud layer to be put on an
  3.  *              earth-like planetary model to model clouds and a cyclone.
  4.  *
  5.  * DESCRIPTION:
  6.  *      When put on a sphere, sets the color & opacity of the sphere to
  7.  *   make it look like the clouds surrounding an Earth-like planet, with
  8.  *   a big cyclone.
  9.  *      The shader works by creating a fractal turbulence function over
  10.  *   the surface, then modulating the opacity based on this function in
  11.  *   a way that looks like clouds on a planetary scale.
  12.  *
  13.  *
  14.  * PARAMETERS:
  15.  *    Ka, Kd - the usual meaning
  16.  *    cloudcolor - the color of the clouds, usually white
  17.  *    max_radius
  18.  *    twist - controls the twisting of the clouds due to the cyclone.
  19.  *    offset, scale - control the linear scaling of the cloud value.
  20.  *    omega, octaves - controls the fractal characteristics of the clouds
  21.  *
  22.  *
  23.  * HINTS:
  24.  *    See the "planetclouds" shader for hints which apply equally well
  25.  *    to this shader.
  26.  *
  27.  *
  28.  * AUTHOR: Ken Musgrave
  29.  *    Conversion to Shading Language and other minor changes by Larry Gritz.
  30.  *
  31.  * REFERENCES:
  32.  *    _Texturing and Modeling: A Procedural Approach_, by David S. Ebert, ed.,
  33.  *    F. Kenton Musgrave, Darwyn Peachey, Ken Perlin, and Steven Worley.
  34.  *    Academic Press, 1994.  ISBN 0-12-228760-6.
  35.  *
  36.  * HISTORY:
  37.  *    ???? - original texture developed by Ken Musgrave.
  38.  *    Feb 1994 - Conversion to Shading Language by L. Gritz
  39.  *
  40.  * last modified 1 March 1994 by lg
  41.  */
  42.  
  43.  
  44.  
  45. #define TWOPI (2*PI)
  46.  
  47. /* Use signed Perlin noise */
  48. #define snoise(x) ((2*noise(x))-1)
  49. #define DNoise(p) (2*(point noise(p)) - point(1,1,1))
  50. #define VLNoise(Pt,scale) (snoise(DNoise(Pt)+(scale*Pt)))
  51. #define VERY_SMALL 0.001
  52.  
  53.  
  54.  
  55.  
  56. surface
  57. cyclone (float Ka = 0.5, Kd = 0.75;
  58.      float max_radius = 1;
  59.      float twist = 0.5;
  60.      float scale = .7, offset = .5;
  61.      float omega = 0.675;
  62.      float octaves = 4;)
  63. {
  64.   float radius, dist, angle, sine, cosine, eye_weight, value;
  65.   point Pt;                 /* Point in texture space */
  66.   point PN;                 /* Normalized vector in texture space */
  67.   point PP;                 /* Point after distortion */
  68.   float l, o, a, i;         /* Loop control for fractal sum */
  69.  
  70.   /* Transform to texture coordinates */
  71.   Pt = transform ("shader", P);
  72.  
  73.   /* Rotate hit point to "cyclone space" */
  74.   PN = normalize (Pt);
  75.   radius = sqrt (xcomp(PN)*xcomp(PN) + ycomp(PN)*ycomp(PN));
  76.  
  77.   if (radius < max_radius) {   /* inside of cyclone */
  78.       /* invert distance from center */
  79.       dist = pow (max_radius - radius, 3);
  80.       angle = PI + twist * TWOPI * (max_radius-dist) / max_radius;
  81.       sine = sin (angle);
  82.       cosine = cos (angle);
  83.       PP = point (xcomp(Pt)*cosine - ycomp(Pt)*sine,
  84.           xcomp(Pt)*sine + ycomp(Pt)*cosine,
  85.           zcomp(Pt));
  86.       /* Subtract out "eye" of storm */
  87.       if (radius < 0.05*max_radius) {  /* if in "eye" */
  88.       eye_weight = (.1*max_radius - radius) * 10;   /* normalize */
  89.       /* invert and make nonlinear */
  90.       eye_weight = pow (1 - eye_weight, 4);
  91.     }
  92.       else eye_weight = 1;
  93.     }
  94.   else PP = Pt;
  95.  
  96.   if (eye_weight > 0) {   /* if in "storm" area */
  97.       /* Compute VLfBm */
  98.       l = 1;  o = 1;  a = 0;
  99.       for (i = 0;  i < octaves  &&  o >= VERY_SMALL;  i += 1) {
  100.       a += o * VLNoise (PP * l, 1);
  101.       l *= 2;
  102.       o *= omega;
  103.     }
  104.       value = abs (eye_weight * (offset + scale * a));
  105.     }
  106.   else value = 0;
  107.  
  108.   /* Thin the density of the clouds */
  109.   Oi = value * Os;
  110.  
  111.   /* Shade like matte, but with color scaled by cloud opacity */
  112.   Ci = Oi * (Ka * ambient() + Kd * diffuse(faceforward(normalize(N),I)));
  113. }
  114.